package se.cbb.misc;


import java.util.ArrayList;

/**
 * 
 * @author Raja Hashim Ali
 *
 */
public class Species {
	/*'******************************************************************************
	 * 							CLASS VARIABLES										*
	 ********************************************************************************/
	private String speciesName;
	private ArrayList<Chromosome> chromosomes;
	private Integer speciesIndex;
	
	public Species(String speciesName) {
		this.speciesName = speciesName;
		chromosomes = new ArrayList<Chromosome>();
	}
	
	public void setAllChromosomes(Chromosome[] listOfChromosome) {
		if(listOfChromosome.length != chromosomes.size()) {
			System.out.println("ERROR: Size of array is not matching with initial declaration in chromosomes");
			return;
		}
		for(int i = 0; i < listOfChromosome.length; i++) 
			chromosomes.add(listOfChromosome[i]);
	}
	
	public void addChromosome(Chromosome chr) {
		chromosomes.add(chr);
	}
	
	public void setChromosomeIndices() {
		for(int i = 0; i < chromosomes.size(); i++) 
			chromosomes.get(i).setIndex(i);
	}
	
	public ArrayList<Chromosome> getChromosomes() 	{ return chromosomes; }
	public String getName() 						{ return speciesName; }
	public void setSpeciesIndex(int speciesIndex) 	{ this.speciesIndex = speciesIndex; }
	public int getspeciesIndex()					{ return speciesIndex; }
	
	public void writeSpeciesInfo(String path) throws Exception {
		int minBlast = 1000;
		int totalBlast = 0;
		int averageBlast = 0;
		int maxBlast = 0;
		String minPoint = "";
		String maxPoint = "";
		for(int i = 0; i < chromosomes.size(); i++) {
			int chromosomeBlast = 0;
			int minChrBlast = 1000;
			int averageChrBlast = 0;
			int maxChrBlast = 0;
			String minChrPoint = "";
			String maxChrPoint = "";
			SequenceFileWriter.writeAndAppendLine(path, "BlastStatistics.log", "----------------- Chr " + speciesIndex + "." + i + " --------------------------");
			for (int j = 0; j < chromosomes.get(i).getGeneList().size(); j++) {
				SequenceFileWriter.writeAndAppendLine(path, "Species.spec", speciesIndex + "\t" + speciesName + "\t" + i + "\t" + chromosomes.get(i).getChrName() + "\t" + j + "\t" + chromosomes.get(i).getGeneList().get(j).getGeneID() + "\t" + chromosomes.get(i).getGeneList().get(j).getStartpos());
				
				for(int k = 0; k < chromosomes.get(i).getGeneList().get(j).getGeneBlastResult().size(); k++) {
					Couple<String, Float> res = chromosomes.get(i).getGeneList().get(j).getGeneBlastResult().get(k);
					SequenceFileWriter.writeAndAppendLine(path, "Species.spec", "\t" + res.first + "\t" + res.second);
				}
				SequenceFileWriter.writeAndAppendLine(path, "BlastStatistics.log", speciesIndex + "." + i + "." + j + "\t" + chromosomes.get(i).getGeneList().get(j).getGeneBlastResult().size());
				totalBlast = totalBlast + chromosomes.get(i).getGeneList().get(j).getGeneBlastResult().size();
				chromosomeBlast = chromosomeBlast + chromosomes.get(i).getGeneList().get(j).getGeneBlastResult().size();
				if(minBlast > chromosomes.get(i).getGeneList().get(j).getGeneBlastResult().size()) {
					minBlast = chromosomes.get(i).getGeneList().get(j).getGeneBlastResult().size();
					minPoint = String.valueOf(speciesIndex) + "." + String.valueOf(i) + "." + String.valueOf(j);
				}
				if(maxBlast < chromosomes.get(i).getGeneList().get(j).getGeneBlastResult().size()) {
					maxBlast = chromosomes.get(i).getGeneList().get(j).getGeneBlastResult().size();
					maxPoint = String.valueOf(speciesIndex) + "." + String.valueOf(i) + "." + String.valueOf(j);
				}
				if(minChrBlast > chromosomes.get(i).getGeneList().get(j).getGeneBlastResult().size()) {
					minChrBlast = chromosomes.get(i).getGeneList().get(j).getGeneBlastResult().size();
					minChrPoint = String.valueOf(speciesIndex) + "." + String.valueOf(i) + "." + String.valueOf(j);
				}
				if(maxChrBlast < chromosomes.get(i).getGeneList().get(j).getGeneBlastResult().size()) {
					maxChrBlast = chromosomes.get(i).getGeneList().get(j).getGeneBlastResult().size();
					maxChrPoint = String.valueOf(speciesIndex) + "." + String.valueOf(i) + "." + String.valueOf(j);
				}
			}
			averageChrBlast = chromosomeBlast / chromosomes.get(i).getGeneList().size();
			SequenceFileWriter.writeAndAppendLine(path, "BlastStatistics.log", "Total = " + chromosomeBlast);
			SequenceFileWriter.writeAndAppendLine(path, "BlastStatistics.log", "Average per gene = " + averageChrBlast);
			SequenceFileWriter.writeAndAppendLine(path, "BlastStatistics.log", "Max Hits = " + maxChrBlast + " at " + maxChrPoint);
			SequenceFileWriter.writeAndAppendLine(path, "BlastStatistics.log", "Min Hits = " + minChrBlast + " at " + minChrPoint);
			SequenceFileWriter.writeAndAppendLine(path, "BlastStatistics.log", "--------------------------------------------------------");
		}
		averageBlast = totalBlast / chromosomes.size();
		SequenceFileWriter.writeAndAppendLine(path, "BlastStatistics.log", "*********************** Species " + speciesIndex + " *********************************");
		SequenceFileWriter.writeAndAppendLine(path, "BlastStatistics.log", "Species Total = " + totalBlast);
		SequenceFileWriter.writeAndAppendLine(path, "BlastStatistics.log", "Average per chromosome = " + averageBlast);
		SequenceFileWriter.writeAndAppendLine(path, "BlastStatistics.log", "Max Hits = " + maxBlast + " at " + maxPoint);
		SequenceFileWriter.writeAndAppendLine(path, "BlastStatistics.log", "Min Hits = " + minBlast + " at " + minPoint);
		SequenceFileWriter.writeAndAppendLine(path, "BlastStatistics.log", "********************************************************");
	}
	
	public void writeSpeciesInfowithNCScore(String path) throws Exception {
		int minBlast = 1000;
		int totalBlast = 0;
		int averageBlast = 0;
		int maxBlast = 0;
		String minPoint = "";
		String maxPoint = "";
		for(int i = 0; i < chromosomes.size(); i++) {
			int chromosomeBlast = 0;
			int minChrBlast = 1000;
			int averageChrBlast = 0;
			int maxChrBlast = 0;
			String minChrPoint = "";
			String maxChrPoint = "";
			SequenceFileWriter.writeAndAppendLine(path, "NCStatistics.log", "----------------- Chr " + speciesIndex + "." + i + " --------------------------");
			for (int j = 0; j < chromosomes.get(i).getGeneList().size(); j++) {
				SequenceFileWriter.writeAndAppendLine(path, "Species.spec", speciesIndex + "\t" + speciesName + "\t" + i + "\t" + chromosomes.get(i).getChrName() + "\t" + j + "\t" + chromosomes.get(i).getGeneList().get(j).getGeneID() + "\t" + chromosomes.get(i).getGeneList().get(j).getStartpos());
				
				for(int k = 0; k < chromosomes.get(i).getGeneList().get(j).getGenencScore().size(); k++) {
					Couple<String, Float> res = chromosomes.get(i).getGeneList().get(j).getGenencScore().get(k);
					Float rxyValue = chromosomes.get(i).getGeneList().get(j).getSyntenyScore().get(k);
					SequenceFileWriter.writeAndAppendLine(path, "Species.spec", "\t" + res.first + "\t" + res.second + "\t" + rxyValue);
				}
				SequenceFileWriter.writeAndAppendLine(path, "NCStatistics.log", speciesIndex + "." + i + "." + j + "\t" + chromosomes.get(i).getGeneList().get(j).getGenencScore().size());
				totalBlast = totalBlast + chromosomes.get(i).getGeneList().get(j).getGenencScore().size();
				chromosomeBlast = chromosomeBlast + chromosomes.get(i).getGeneList().get(j).getGenencScore().size();
				if(minBlast > chromosomes.get(i).getGeneList().get(j).getGenencScore().size()) {
					minBlast = chromosomes.get(i).getGeneList().get(j).getGenencScore().size();
					minPoint = String.valueOf(speciesIndex) + "." + String.valueOf(i) + "." + String.valueOf(j);
				}
				if(maxBlast < chromosomes.get(i).getGeneList().get(j).getGenencScore().size()) {
					maxBlast = chromosomes.get(i).getGeneList().get(j).getGenencScore().size();
					maxPoint = String.valueOf(speciesIndex) + "." + String.valueOf(i) + "." + String.valueOf(j);
				}
				if(minChrBlast > chromosomes.get(i).getGeneList().get(j).getGenencScore().size()) {
					minChrBlast = chromosomes.get(i).getGeneList().get(j).getGenencScore().size();
					minChrPoint = String.valueOf(speciesIndex) + "." + String.valueOf(i) + "." + String.valueOf(j);
				}
				if(maxChrBlast < chromosomes.get(i).getGeneList().get(j).getGenencScore().size()) {
					maxChrBlast = chromosomes.get(i).getGeneList().get(j).getGenencScore().size();
					maxChrPoint = String.valueOf(speciesIndex) + "." + String.valueOf(i) + "." + String.valueOf(j);
				}
			}
			averageChrBlast = chromosomeBlast / chromosomes.get(i).getGeneList().size();
			SequenceFileWriter.writeAndAppendLine(path, "NCStatistics.log", "Total = " + chromosomeBlast);
			SequenceFileWriter.writeAndAppendLine(path, "NCStatistics.log", "Average per gene = " + averageChrBlast);
			SequenceFileWriter.writeAndAppendLine(path, "NCStatistics.log", "Max Hits = " + maxChrBlast + " at " + maxChrPoint);
			SequenceFileWriter.writeAndAppendLine(path, "NCStatistics.log", "Min Hits = " + minChrBlast + " at " + minChrPoint);
			SequenceFileWriter.writeAndAppendLine(path, "NCStatistics.log", "--------------------------------------------------------");
		}
		averageBlast = totalBlast / chromosomes.size();
		SequenceFileWriter.writeAndAppendLine(path, "NCStatistics.log", "*********************** Species " + speciesIndex + " *********************************");
		SequenceFileWriter.writeAndAppendLine(path, "NCStatistics.log", "Species Total = " + totalBlast);
		SequenceFileWriter.writeAndAppendLine(path, "NCStatistics.log", "Average per chromosome = " + averageBlast);
		SequenceFileWriter.writeAndAppendLine(path, "NCStatistics.log", "Max Hits = " + maxBlast + " at " + maxPoint);
		SequenceFileWriter.writeAndAppendLine(path, "NCStatistics.log", "Min Hits = " + minBlast + " at " + minPoint);
		SequenceFileWriter.writeAndAppendLine(path, "NCStatistics.log", "********************************************************");
	}
}
